package uk.ac.nott.cs.g53dia.bee;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import uk.ac.nott.cs.g53dia.Action;
import uk.ac.nott.cs.g53dia.Bee;
import uk.ac.nott.cs.g53dia.Cell;
import uk.ac.nott.cs.g53dia.CreateNestAction;
import uk.ac.nott.cs.g53dia.DepositNectarAction;
import uk.ac.nott.cs.g53dia.EmptyCell;
import uk.ac.nott.cs.g53dia.Environment;
import uk.ac.nott.cs.g53dia.Flower;
import uk.ac.nott.cs.g53dia.HarvestAction;
import uk.ac.nott.cs.g53dia.LayEggAction;
import uk.ac.nott.cs.g53dia.MoveAction;
import uk.ac.nott.cs.g53dia.MoveTowardsAction;
import uk.ac.nott.cs.g53dia.Nest;
import uk.ac.nott.cs.g53dia.Point;
import uk.ac.nott.cs.g53dia.RestAction;
import utils.General;
import utils.RandomGenerator;
/**
 * A simple example bee that chooses actions at random.
 * 
 * @author Neil Madden.
 */
/*
 * Copyright (c) 2005 Neil Madden.
 * 
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */
public class DemoBee extends Bee {
	
    public DemoBee(int id) {
    	super(id);
    	cells = new HashMap<Point, Cell>();
    }

    // Location of the bee's nest - null if the bee has yet to create a nest
    Point nest_loc = null;
    // Location of the most recently sensed flower - null if bee has yet to sense a flower
    Point last_fl_loc = null;
    
    private Map<Point, Cell> cells;
    private Map<String, Map<Long, Integer>> samples; // "red".12L = 10

    /*
     * The following is a very simple demonstration of how to write a bee. The
     * code below is very stupid and pretty much randomly picks actions to
     * perform. You can use this file as a template for writing your own bee,
     * but DO NOT USE THIS CODE. That would be plagiarism.
     */
    public Action senseAndAct(Cell[][] view, long timestep) {
    	updateKnowledge(view);
    	
        // If energy level is below a threshold, then rest
        if (getEnergy() < 10) {
            return new RestAction();
        }

        //The following is an illustration of how to evaluate the time of day - it isn't used in the demobee
        long timeOfDay = (timestep % Environment.DAY_LENGTH);
        
        // Do we have a nest yet?
        if (nest_loc == null) {
            // No - can we create one?
            if (getEnergy() > Nest.NEST_COST) {
                // Yes - is current cell free?
                if (getCurrentCell(view) instanceof EmptyCell) {
                    nest_loc = getPosition();
                    return new CreateNestAction();
                } else {
                    // Move elsewhere
                    return new MoveAction(RandomGenerator.getRandomInt(8));
                }
            }
        } else {
            // We have a nest - are we at it?
            if (getPosition().equals(nest_loc)) {
                // Yes.
                Nest n = (Nest)getCurrentCell(view);
                // Is it ready for an egg?
                if (n.foodSupply() >= Nest.EGG_COST) {
                    return new LayEggAction();
                }
                // Do we have enough energy to put some in it?
                if (getEnergy() > 100) {
                    return new DepositNectarAction(getEnergy() - 50);
                }
            } else {
                // Do we have a decent amount of energy?
                if (RandomGenerator.getRandomInt(100)+100 < getEnergy()) {
                    return new MoveTowardsAction(nest_loc);
                }
            }
        }
        // Fallback - look for a flower to harvest
        if (getCurrentCell(view) instanceof Flower) {
            last_fl_loc = getPosition();
            return new HarvestAction();
        }
        // Where did we last see a flower?
        if (last_fl_loc != null) {
            return new MoveTowardsAction(last_fl_loc);
        }
        // Find a flower...
        return new MoveAction(RandomGenerator.getRandomInt(8));
    }
    
    private boolean updateKnowledge(Cell[][] view) {
    	Cell[][] copy = General.deepCopy(view);
    	for (Cell[] row : copy) {
    		for (Cell cell : row) {
    			cells.put(cell.getPoint(), cell);
    		}
    	}
    	return true;
    }
    
    public Map<Point, Cell> getCells() {
    	return cells;
    }

	@Override
	public Bee clone() {
		DemoBee newBee = new DemoBee(getId());
		newBee.setPosition(getPosition());
		return newBee;
	}

	@Override
	public void addCells(Map<Point, Cell> cells) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public List<Set<Point>> getFlowersOfType() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int updateFlowersPositions(List<Set<Point>> flowersOfType) {
		// TODO Auto-generated method stub
		return 0;
	}

  @Override
  public Role getRole() {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void communicate(Bee bee) {
    // TODO Auto-generated method stub
    
  }

  @Override
  public List<Map<Long, Integer>> getSamples() {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public int updateFlowersYields(List<Map<Long, Integer>> samples) {
    // TODO Auto-generated method stub
    return 0;
  }
}
